(function () { "use strict"; var cfg = window.VSL_CONFIG; if (!cfg) { console.error("[VSL] Config não carregado (vsl-config.php ou config.js)."); return; } var analytics = window.VSL_ANALYTICS || null; var sentMilestones = {}; var sessionId = (function () { var key = "kks_vsl_session"; try { var id = localStorage.getItem(key); if (!id) { id = "sess_" + Math.random().toString(36).slice(2) + Date.now().toString(36); localStorage.setItem(key, id); } return id; } catch (e) { return "sess_" + Date.now(); } })(); function parseUtms() { var params = new URLSearchParams(window.location.search); return { utm_source: params.get("utm_source") || "", utm_medium: params.get("utm_medium") || "", utm_campaign: params.get("utm_campaign") || "", utm_content: params.get("utm_content") || "", utm_term: params.get("utm_term") || "", fbclid: params.get("fbclid") || "", gclid: params.get("gclid") || "", ttclid: params.get("ttclid") || "", }; } var utms = parseUtms(); function track(eventName, extra) { if (!analytics || !analytics.events_url) return; var payload = { embed_id: analytics.embed_id, video_id: analytics.video_id, project_id: analytics.project_id, event_name: eventName, session_id: sessionId, current_time: video ? video.currentTime : 0, duration: video && video.duration ? video.duration : 0, percent: 0, url: window.location.href, referrer: document.referrer || "", user_agent: navigator.userAgent || "", }; Object.assign(payload, utms); if (extra) Object.assign(payload, extra); if (payload.duration > 0) { payload.percent = Math.min(100, (payload.current_time / payload.duration) * 100); } var body = JSON.stringify(payload); try { if (navigator.sendBeacon) { navigator.sendBeacon( analytics.events_url, new Blob([body], { type: "text/plain;charset=UTF-8" }) ); return; } } catch (e) {} fetch(analytics.events_url, { method: "POST", headers: { "Content-Type": "application/json" }, body: body, keepalive: true, credentials: "omit", mode: "cors", }).catch(function () {}); } var container = document.getElementById(cfg.containerId || "vsl-player"); if (!container) { console.error("[VSL] Container não encontrado:", cfg.containerId); return; } var layout = cfg.layout || {}; var loadingCfg = cfg.loading || {}; var overlayCfg = cfg.overlay || {}; var progressCfg = cfg.progressBar || {}; var videoCfg = cfg.video || {}; container.className = "vsl-player"; container.classList.remove("kks-embed-loading"); container.style.minHeight = ""; container.style.background = ""; container.innerHTML = '
' + '' + '
' + '
' + '
' + (loadingCfg.startPercent || 50) + '%
' + '
' + '' + '' + '
' + '
' + '
' + '
'; var wrapper = container.querySelector(".vsl-wrapper"); var video = container.querySelector(".vsl-video"); var loading = container.querySelector(".vsl-loading"); var percentEl = container.querySelector(".vsl-percent"); var overlay = container.querySelector(".vsl-overlay"); var progress = container.querySelector(".vsl-fake-progress"); var spinner = container.querySelector(".vsl-spinner"); var fakeBar = container.querySelector(".vsl-fake-bar"); var tapBtn = container.querySelector(".vsl-tap-btn"); wrapper.style.aspectRatio = layout.aspectRatio || "16 / 9"; wrapper.style.background = layout.background || "#000"; wrapper.style.borderRadius = layout.borderRadius || "0"; if (layout.maxWidth) { container.style.maxWidth = layout.maxWidth; container.style.width = "100%"; container.style.marginLeft = "auto"; container.style.marginRight = "auto"; } if (overlayCfg.background) { overlay.style.setProperty("--vsl-overlay-bg", overlayCfg.background); overlay.style.background = overlayCfg.background; } if (overlayCfg.borderColor) { overlay.style.setProperty("--vsl-overlay-border", overlayCfg.borderColor); overlay.style.borderColor = overlayCfg.borderColor; } if (loadingCfg.spinnerColor && spinner) { spinner.style.borderTopColor = loadingCfg.spinnerColor; } var barHeight = progressCfg.heightPx || 10; fakeBar.style.height = barHeight + "px"; fakeBar.style.background = progressCfg.trackColor || "rgba(255,255,255,0.2)"; progress.style.background = progressCfg.color || "#3D85C6"; var percent = loadingCfg.startPercent || 50; var maxPercent = loadingCfg.maxPercent || 99; var hlsInstance = null; var autoplayStarted = false; track("page_view"); var fakeLoad = setInterval(function () { if (percent < maxPercent) { percent++; percentEl.textContent = percent + "%"; } }, loadingCfg.tickIntervalMs || 35); function hideLoading() { loading.style.display = "none"; clearInterval(fakeLoad); } function showOverlay() { hideLoading(); overlay.style.display = "flex"; } async function tryMutedAutoplay() { if (autoplayStarted) return; autoplayStarted = true; video.muted = videoCfg.mutedOnAutoplay !== false; video.playsInline = videoCfg.playsinline !== false; video.controls = false; try { await video.play(); track("video_play"); showOverlay(); } catch (e) { showOverlay(); } } var fallbackTimer = setTimeout(showOverlay, loadingCfg.fallbackMs || 3000); function playerReady() { clearTimeout(fallbackTimer); track("video_loaded"); tryMutedAutoplay(); } function setupHls() { if (window.Hls && Hls.isSupported()) { hlsInstance = new Hls(cfg.hls || {}); hlsInstance.loadSource(cfg.streamUrl); hlsInstance.attachMedia(video); hlsInstance.on(Hls.Events.MANIFEST_PARSED, function () { playerReady(); }); hlsInstance.on(Hls.Events.ERROR, function (event, data) { console.warn("[VSL] Erro HLS:", data); if (data && data.fatal) { switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: hlsInstance.startLoad(); break; case Hls.ErrorTypes.MEDIA_ERROR: hlsInstance.recoverMediaError(); break; default: hlsInstance.destroy(); track("video_error"); showOverlay(); break; } } }); return; } if (video.canPlayType("application/vnd.apple.mpegurl")) { video.src = cfg.streamUrl; video.addEventListener("loadedmetadata", playerReady, { once: true }); video.load(); return; } console.error("[VSL] Este navegador não suporta HLS."); track("video_error"); showOverlay(); } setupHls(); // Fluxo VTurb: 1º toque mostra ícone; 2º pausa; some em ~3s se não confirmar var allowTogglePause = false; var tapHideTimer = null; var TAP_HIDE_MS = 3000; function clearTapHideTimer() { if (tapHideTimer) { clearTimeout(tapHideTimer); tapHideTimer = null; } } function hideTapBtn() { clearTapHideTimer(); tapBtn.hidden = true; tapBtn.classList.remove("is-paused", "is-armed"); } function showTapBtn(mode) { clearTapHideTimer(); tapBtn.hidden = false; tapBtn.classList.toggle("is-paused", mode === "paused"); tapBtn.classList.toggle("is-armed", mode === "armed"); tapBtn.setAttribute("aria-label", mode === "paused" ? "Reproduzir" : "Pausar"); if (mode === "armed") { tapHideTimer = setTimeout(function () { if (!video.paused) hideTapBtn(); }, TAP_HIDE_MS); } } overlay.addEventListener("click", async function () { overlay.style.display = "none"; hideLoading(); allowTogglePause = true; hideTapBtn(); video.muted = false; video.controls = false; if (videoCfg.restartOnUnmute) { try { video.currentTime = 0; } catch (e) {} } track("video_unmute_click"); try { await video.play(); } catch (e) { if (videoCfg.showNativeControlsOnFallback !== false) { video.controls = true; } video.muted = false; video.play().catch(function () {}); } }); tapBtn.addEventListener("click", function (e) { e.preventDefault(); e.stopPropagation(); if (!allowTogglePause || video.controls) return; if (video.paused) { video.play().catch(function () {}); hideTapBtn(); return; } // 2º toque no ícone armado → pausa if (tapBtn.classList.contains("is-armed")) { video.pause(); showTapBtn("paused"); return; } showTapBtn("armed"); }); wrapper.addEventListener("click", function (e) { if (!allowTogglePause) return; if (e.target.closest(".vsl-overlay")) return; if (e.target.closest(".vsl-tap-btn")) return; if (video.controls) return; e.preventDefault(); if (video.paused) { video.play().catch(function () {}); hideTapBtn(); return; } // Já armado: 2º toque em qualquer lugar do vídeo também pausa if (tapBtn.classList.contains("is-armed") && !tapBtn.hidden) { video.pause(); showTapBtn("paused"); return; } // 1º toque: só mostra o ícone (evita miss-click) showTapBtn("armed"); }); video.addEventListener("play", function () { if (allowTogglePause && !tapBtn.classList.contains("is-armed")) { hideTapBtn(); } }); video.addEventListener("pause", function () { if (!allowTogglePause || video.controls) return; if (video.ended) { hideTapBtn(); return; } showTapBtn("paused"); }); video.addEventListener("playing", hideLoading); video.addEventListener("timeupdate", function () { if (video.duration && isFinite(video.duration) && progress) { var pct = (video.currentTime / video.duration) * 100; progress.style.width = pct + "%"; [25, 50, 75, 100].forEach(function (m) { if (pct >= m && !sentMilestones[m]) { sentMilestones[m] = true; track("video_" + m); } }); } }); video.addEventListener("pause", function () { track("video_pause"); }); video.addEventListener("ended", function () { if (progress) progress.style.width = "100%"; track("video_100"); }); document.addEventListener("click", function (e) { var cta = e.target.closest("[data-vsl-cta]"); if (cta && analytics && analytics.events_url) { track("cta_click"); } }); })();